﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AudioCtrl;
using USBDeviceCtrl;
using System.IO;
using System.Configuration;

namespace DictationManager
{
    public class CoreManager
    {
        AudioLib _audio;
        PhilipsManager _device;
        bool _dictationMode;
        bool success;
        StreamWriter _logsFile;
        String _logPath;

        public delegate void LoadingHandler(object sender, LoadArgs args);
        public event LoadingHandler dictationLoaded;

        public delegate void ConnectionHandler(object sender, LoadArgs args);
        public event LoadingHandler deviceConnection;

        public delegate void EOLHandler(object sender, LoadArgs args);
        public event EOLHandler EOLButtonPressed;

        public delegate void NoFileFoundHandler(object sender, FileArgs args);
        public event NoFileFoundHandler fileNotFound;

        public CoreManager()
        {
            InstanceLogs();
            WriteInLogs("Initializing Program");
            _dictationMode = true;
            try
            {
                WriteInLogs("Initializing Controllers");
                _audio = new AudioLib();
                _device = new PhilipsManager();
                _device.eventButton += new PhilipsManager.ButtonHandler(_device_eventButton);
                _device.deviceConnected += new PhilipsManager.ConnectionHandler(_device_deviceConnected);
                if (_audio.recordMode.Equals("Insert"))
                    _device.RecordModeLight(0);
                else
                    _device.RecordModeLight(1);
            }
            catch (Exception ex)
            {
                WriteInLogs("Exception loading Controllers \n" + ex.Message);
                throw (ex);
            }
        }

        void _device_deviceConnected(object sender, buttonArgs args)
        {
            WriteInLogs("A device found");
            deviceConnection(this, new LoadArgs(0));
        }

        void _device_eventButton(object sender, buttonArgs args)
        {
            WriteInLogs("Button " + args.button + " pressed since device");
            switch (args.button)
            {
                case ("Play"):
                    EventButton("Play", "Pressed");
                    break;
                case ("PlayStopToggle"):
                    EventButton("Play", "Pressed");
                    break;
                case ("Record"):
                    EventButton("Record", "Pressed");
                    break;
                case ("Stop"):
                    EventButton("Stop", "Pressed");
                    break;
                case ("Insert"):
                    EventButton("Insert", "Pressed");
                    break;
                case ("EOL"):
                    EventButton("EOL", "Pressed");
                    break;
                case ("FForwardPressed"):
                    EventButton("FForward", "Pressed");
                    break;
                case ("FRewindPressed"):
                    EventButton("FRewind", "Pressed");
                    break;
                case ("FForwardReleased"):
                    EventButton("FForward", "Released");
                    break;
                case ("FRewindReleased"):
                    EventButton("FRewind", "Released");
                    break;
                    
            }
        }

        public void LoadDictation(String[] parameters, bool createNew)
        {
            WriteInLogs("Loading dictation : \nFilePath: " + parameters[0] + "\nDictation Mode: " + parameters[1] + "\nPID: " + parameters[2] + "\nPatient Name: " + parameters[3] + "\nAccession Num: " + parameters[4] + "\nStudy: " + parameters[5] + "\nRadiologist: " + parameters[6] + "\nDateTime: " + parameters[7]);
            success = true;
            _dictationMode = bool.Equals(parameters[1], "0");

            if (createNew)
            {
                WriteInLogs("Creating new dictation");
                _audio.CreateFile(parameters, false);
            }
            else
            {
                WriteInLogs("Loading already exist dictation");
                success = _audio.LoadFile(parameters[0], false);
            }
            if (success)
            {
                WriteInLogs("Successfull process");
                dictationLoaded(this, new LoadArgs(_audio.length));
            }
            else
            {
                WriteInLogs("Trouble was detected loading dictation (file not found)");
                fileNotFound(this, new FileArgs(parameters[0]));
            }
        }

        public bool SaveDictation()
        {
            WriteInLogs("Saving dictation");
            bool result;
            _audio.Stop();
            result = _audio.SaveNewFile();
            WriteInLogs("Saving success : " + result);
            return result;
        }

        public void EventButton(String button, String buttonEvent)
        {
            WriteInLogs("Executing " + button + " " + buttonEvent);
            if (success)
            {
                if (buttonEvent == "Pressed")
                {
                    _device.LightsOff();
                    switch (button)
                    {
                        case "Play":
                            _audio.Play();
                            _device.GreenLight(_audio.IsPlaying);
                            break;
                        case "Stop":
                            _audio.Stop();
                            break;
                        case "Record":
                            if (_dictationMode)
                            {
                                _audio.Record();
                                _device.RedLight(_audio.IsRecording);
                            }
                            break;
                        case "FForward":
                            _audio.FForward();
                            break;
                        case "FRewind":
                            _audio.FRewind();
                            break;
                        case "EOL":
                            EOLButtonPressed(this, new LoadArgs(0));
                            break;
                        case "Insert":
                            {
                                _audio.setRecordMode();
                                if (_audio.recordMode.Equals("Insert"))
                                
                                    _device.RecordModeLight(0);
                                else
                                    _device.RecordModeLight(1);
                            }
                            break;
                    }
                }
                if (buttonEvent == "Released")
                {
                    switch (button)
                    {
                        case "FForward":
                            _audio.Stop();
                            break;
                        case "FRewind":
                            _audio.Stop();
                            break;
                    }
                }
            }
        }

        private void InstanceLogs()
        {
            //ActivateLogs
            if (ConfigurationManager.AppSettings["ActivateLogs"].ToString().ToUpper().Equals("TRUE"))
            {
                _logPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\MedSpeech\MedSpeech " + DateTime.Today.ToString("yyyy MM dd") + ".log";
                string onlyPath = _logPath.Substring(0, _logPath.LastIndexOf('\\'));
                if (!Directory.Exists(onlyPath))
                    Directory.CreateDirectory(onlyPath);
                _logsFile = new StreamWriter(_logPath, true);
            }
        }

        private void WriteInLogs(string message)
        {
            if (ConfigurationManager.AppSettings["ActivateLogs"].ToString().ToUpper().Equals("TRUE"))
                _logsFile.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " " + message);
        }

        public int currentPosition
        {
            get { return _audio.position; }
        }

        public int fileLength
        {
            get { return _audio.length; }
        }

        public int outputVolume
        {
            get { return _audio.SpeakerVolume; }
            set { _audio.SpeakerVolume = value; }
        }

        public int inputVolume
        {
            get { return _audio.MicVolume; }
            set { _audio.MicVolume = value; }
        }

        public bool ExistPreviousDictation
        {
            get { return _audio.fileLoaded; }
        }

        public string FileTargetPath
        {
            get { return _audio.targetFilePath; }
        }

        public void DiscardDictation()
        {
            WriteInLogs("Discarting previous dictation");
            _audio.CloseFile();
        }

        public void FreeComponents()
        {
            WriteInLogs("Free resources");
            _device.OffLights();
            _device.FreeManager();
            WriteInLogs("Closing logs");
            _logsFile.Close();
        }

        public void GoToStart()
        {
            _audio.GoToStart();
        }

        public bool IsDeviceRecordConnected()
        {
            return _device.IsRecordConnected;
        }
    }

    public class LoadArgs
    {
        int _length;
        public LoadArgs(int length)
        {
            _length = length;
        }

        public int length
        {
            get { return _length; }
        }
    }

    public class FileArgs
    {
        string audioFileName;
        public FileArgs(string _fileName)
        {
            audioFileName = _fileName;
        }

        public string fileName
        {
            get { return audioFileName; }
        }
    }
}